package com.syswin.lhztest.model;

import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.ReentrantLock;

public class BulletsBlockingQueue {
    private Queue<Bullet> queue;

    private ReentrantLock lock;
//    private Condition condition;
    private static int maxSize = 6;

    public BulletsBlockingQueue() {
        queue = new LinkedBlockingQueue<>();
        lock = new ReentrantLock();
    }

    //子弹入膛
    public void push(Bullet bullet) {
        lock.lock();
        while (queue.size() >= maxSize) {

            try {
                queue.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("子弹已满，等待消费，子弹数量：" + queue.size());
        }
            System.out.println("装子弹，子弹数量："+queue.size());
            queue.add(bullet);
        queue.notifyAll();
        lock.unlock();
    }

    //子弹出膛
    public Bullet pop() {
        lock.lock();
        Bullet result = null;
        while(queue.size() == 0) {

            try {
                queue.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("子弹已空，待装填"+queue.size());

        }
        System.out.println("消费子弹: 子弹数量"+queue.size());
        result = queue.poll();
        queue.notifyAll();
//        condition.signal();
        lock.unlock();
        return result;
    }


    /**
     * 消费者
     *
     */
    static class BulletPopRunnable implements Runnable {
        private BulletsBlockingQueue bbq = null;
        BulletPopRunnable(BulletsBlockingQueue bbq){
            this.bbq = bbq;
        }
        public void run() {
            try {
                while (true) {
                    bbq.pop();
                    Thread.sleep(100);
                }
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }

        }
    }

    /**
     * 生产者
     *
     */
    static class BulletPushRunnable implements Runnable {
        private BulletsBlockingQueue bbq = null;
        BulletPushRunnable(BulletsBlockingQueue bbq){
            this.bbq = bbq;
        }
        public void run() {
            try {
                while (true) {
                    bbq.push(new Bullet());
                    Thread.sleep(100);
                }
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        BulletsBlockingQueue bbq = new BulletsBlockingQueue();
        BulletPushRunnable bulletPushRunnable1 = new BulletPushRunnable(bbq);
        BulletPopRunnable bulletPopRunnable1 = new BulletPopRunnable(bbq);
        new Thread(bulletPushRunnable1).start();
        new Thread(bulletPopRunnable1).start();

//        BulletPushRunnable bulletPushRunnable2 = new BulletPushRunnable(bbq);
//        BulletPopRunnable bulletPopRunnable2 = new BulletPopRunnable(bbq);
//        new Thread(bulletPushRunnable2).start();
//        new Thread(bulletPopRunnable2).start();
//
//        BulletPushRunnable bulletPushRunnable3 = new BulletPushRunnable(bbq);
//        BulletPopRunnable bulletPopRunnable3 = new BulletPopRunnable(bbq);
//        new Thread(bulletPushRunnable3).start();
//        new Thread(bulletPopRunnable3).start();
    }
}